package ui

import (
	_ "embed"
	"fmt"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/layout"
	"gomoku/ai"
	"image/color"
	"math"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)

var board = ai.NewBoard(SIZE)

type BoardUI struct {
	win          fyne.Window
	size         int     //棋盘大小
	cSize        float32 // 棋子大小
	turnover     bool    // 用于交替出现黑白棋子
	gameStarted  bool    // 游戏是否开始
	bgColor      color.NRGBA
	blackChess   *fyne.StaticResource
	whiteChess   *fyne.StaticResource
	btnList      []*widget.Button
	scoreTipList []*canvas.Text
	timerLabel   *GameTime
	container    *fyne.Container
	rect         *canvas.Rectangle
	blackTime    time.Duration
	whiteTime    time.Duration
}

func NewBoardUI(size int, cSize float32, window fyne.Window) *BoardUI {
	return &BoardUI{
		win:          window,
		size:         size,
		cSize:        cSize,
		turnover:     true,
		gameStarted:  false,
		bgColor:      color.NRGBA{R: 245, G: 245, B: 220, A: 255},
		blackChess:   fyne.NewStaticResource("black.png", blackChessSource),
		whiteChess:   fyne.NewStaticResource("white.png", whiteChessSource),
		btnList:      make([]*widget.Button, size*size),
		scoreTipList: make([]*canvas.Text, size*size),
		timerLabel:   NewGameTime(),
		blackTime:    0,
		whiteTime:    0,
	}
}
func (b *BoardUI) resetBoard() {
	b.turnover = true
	b.gameStarted = false
	b.blackTime = 0
	b.whiteTime = 0
	b.timerLabel.Reset()
	if b.rect != nil {
		b.container.Remove(b.rect)
	}
	for i := 0; i < b.size; i++ {
		for j := 0; j < b.size; j++ {
			n := i*b.size + j
			b.btnList[n].Icon = nil
			b.btnList[n].SetText("")
			b.btnList[n].Refresh()
			if b.scoreTipList[n] != nil {
				b.container.Remove(b.scoreTipList[n])
			}
		}
	}
	board = ai.NewBoard(b.size)
}

func (b *BoardUI) drawLastPieceRect(btn *widget.Button) {
	// 标记最后一个落子的位置
	if b.rect != nil {
		b.container.Remove(b.rect)
	}
	b.rect = canvas.NewRectangle(color.NRGBA{R: 255, G: 0, B: 0, A: 0})
	scale := float32(0.8)
	b.rect.Resize(fyne.NewSize(b.cSize*scale, b.cSize*scale))
	b.rect.StrokeWidth = 2
	b.rect.StrokeColor = color.NRGBA{R: 255, G: 0, B: 0, A: 255}
	b.rect.Move(btn.Position().AddXY(b.cSize*(1.0-scale)/2, b.cSize*(1.0-scale)/2))
	b.container.Add(b.rect)
}

func (b *BoardUI) drawValidScores(validScores map[int]int) {
	// 绘制有效位置的分数
	for _, c := range b.scoreTipList {
		if c != nil {
			b.container.Remove(c)
		}
	}
	for index, score := range validScores {
		formattedScore := fmt.Sprintf("%.1f", math.Log10(float64(score)))
		b.scoreTipList[index].Text = formattedScore
		b.scoreTipList[index].TextSize = 10
		b.scoreTipList[index].Refresh()
		b.container.Add(b.scoreTipList[index])
	}
}

func (b *BoardUI) onClicked(index int) {
	btn := b.btnList[index]
	if !b.gameStarted {
		dialog.ShowInformation("Game not started", "Please click the start button to start the game", b.win)
		return
	}
	if btn.Icon != nil {
		dialog.ShowInformation("Invalid operation", "This position has been occupied", b.win)
		return
	}
	// 逻辑操作
	x, y := index/b.size, index%b.size
	board.Move(x, y)
	b.drawValidScores(board.GetPositionScores())

	if b.turnover {
		btn.Icon = b.blackChess
	} else {
		btn.Icon = b.whiteChess
	}
	b.turnover = !b.turnover
	btn.Refresh()
	btn.Show()

	// 标记最后一个落子的位置
	b.drawLastPieceRect(btn)

}
func (b *BoardUI) startTick() {
	for range time.Tick(time.Second) {
		if b.gameStarted {
			if b.turnover {
				b.blackTime += time.Second
				b.timerLabel.SetBlackTime(b.blackTime)
			} else {
				b.whiteTime += time.Second
				b.timerLabel.SetWhiteTime(b.whiteTime)
			}
		}
	}
}
func (b *BoardUI) init() {

	// 刷新，初始化相关数据
	btnRefresh := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), b.resetBoard)
	btnStart := widget.NewButtonWithIcon("", theme.MediaPlayIcon(), func() {
		b.gameStarted = true
		// 启动计时器
		go b.startTick()
	})

	bg := canvas.NewRectangle(b.bgColor)
	bg.Resize(fyne.NewSquareSize(b.cSize * (float32)(b.size-1)))

	xDelta, yDelta := b.cSize/2, b.cSize/2
	// 棋盘容器
	b.container = container.NewWithoutLayout(bg)
	for i := 0; i < b.size; i++ {
		for j := 0; j < b.size; j++ {
			index := i*b.size + j
			position := fyne.NewPos(xDelta+float32(j)*b.cSize-b.cSize/2, yDelta+float32(i)*b.cSize-b.cSize/2)
			// 绘制button
			btn := widget.NewButtonWithIcon("", nil, func() { b.onClicked(index) })
			btn.Resize(fyne.NewSquareSize(b.cSize))
			btn.Move(position)
			b.btnList[index] = btn
			b.container.Add(btn)
			// 绘制label
			text := canvas.NewText("", color.NRGBA{R: 0, G: 0, B: 0, A: 255})
			text.TextSize = 10
			b.scoreTipList[index] = text
			text.Move(position.Add(fyne.NewPos(0, -b.cSize/4)))
			b.container.Add(text)
		}
	}
	// 画网格线
	lineLength := b.cSize * (float32)(b.size-1)
	for i := 0; i < b.size; i++ {
		// 15条横线
		fVal := float32(i)
		b.container.Add(b.newLine(nil, xDelta, yDelta+fVal*b.cSize, xDelta+lineLength, yDelta+fVal*b.cSize))
		// 15条竖线
		b.container.Add(b.newLine(nil, xDelta+fVal*b.cSize, yDelta, xDelta+fVal*b.cSize, yDelta+lineLength))
	}
	// 画中心点
	// Draw a black dot at the 7x7 position
	dots := [][]float32{{3, 3}, {3, 11}, {11, 3}, {11, 11}, {7, 7}}
	for _, pos := range dots {
		x, y := pos[0], pos[1]
		size := float32(3)
		if x == 7 && y == 7 {
			size = float32(6)
		}
		dot := canvas.NewCircle(color.Black)
		dot.Resize(fyne.NewSize(size, size)) // adjust the size as needed
		dot.Move(fyne.NewPos(xDelta+x*b.cSize-size/2, yDelta+y*b.cSize-size/2))
		b.container.Add(dot)
	}
	topTipHBox := container.NewHBox(btnStart, btnRefresh, layout.NewSpacer(), b.timerLabel.GetWidget(), layout.NewSpacer())
	c := container.NewBorder(topTipHBox, nil, nil, nil, b.container)

	b.win.SetContent(c)
}

func (b *BoardUI) newLine(c color.Color, x1, y1, x2, y2 float32) *canvas.Line {
	if c == nil {
		c = color.NRGBA{R: 50, G: 50, B: 50, A: 100}
	}
	l := canvas.NewLine(c)
	l.Position1 = fyne.NewPos(x1, y1)
	l.Position2 = fyne.NewPos(x2, y2)
	l.StrokeWidth = 1
	return l
}

func (b *BoardUI) checkWin() {

}

const (
	SIZE   = 15
	CELL   = 30
	WIDTH  = SIZE * CELL * 1.02
	HEIGHT = SIZE * CELL * 1.1
)

func Show() {
	a := app.NewWithID("gomoku")
	a.Settings().SetTheme(theme.LightTheme())
	w := a.NewWindow("Gomoku AI")
	w.Resize(fyne.NewSize(WIDTH, HEIGHT))
	w.SetFixedSize(true)
	w.CenterOnScreen()

	NewBoardUI(SIZE, CELL, w).init()

	w.ShowAndRun()
}
